using lucere.toolkit;

namespace lucere.service.search.collect
{
	///<summary>
	/// A base class for all collectors that return a <see cref="TopDocs"/> output. This
	/// collector allows easy extension by providing a single constructor which
	/// accepts a <see cref="IPriorityQueue{T}"/> as well as protected members for that
	/// priority queue and a counter of the number of total hits.<br/>
	/// Extending classes can override <see cref="GetTopDocs(int, int)"/> and
	/// <see cref="TotalHits()"/> in order to provide their own implementation.
	///</summary>
	public interface ITopDocsCollector<T> : ICollector where T : IScoreDoc
	{
		/// <summary>
		/// The total number of documents that matched this query.
		/// </summary>
		int TotalHits { get; }

		/// <summary>
		/// Returns the top docs that were collected by this collector.
		/// </summary>
		ITopDocs TopDocs { get; }


		///<summary>
		/// Returns the documents in the rage [start .. pq.size()) that were collected
		/// by this collector. Note that if start >= pq.size(), an empty TopDocs is
		/// returned.<br/>
		/// This method is convenient to call if the application always asks for the
		/// last results, starting from the last 'page'.<br>
		/// <b>NOTE:</b> you cannot call this method more than once for each search
		/// execution. If you need to call it more than once, passing each time a
		/// different <code>start</code>, you should call <see cref="TopDocs"/> and work
		/// with the returned <see cref="ITopDocs"/> object, which will contain all the
		/// results this search execution collected.</br>
		///</summary>
		ITopDocs GetTopDocs(int start);

		///<summary>
		/// Returns the documents in the rage [start .. start+howMany) that were
		/// collected by this collector. Note that if start >= pq.size(), an empty
		/// TopDocs is returned, and if pq.size() - start &lt; howMany, then only the
		/// available documents in [start .. pq.size()) are returned.<br>
		/// This method is useful to call in case pagination of search results is
		/// allowed by the search application, as well as it attempts to optimize the
		/// memory used by allocating only as much as requested by howMany.<br>
		/// <b>NOTE:</b> you cannot call this method more than once for each search
		/// execution. If you need to call it more than once, passing each time a
		/// different range, you should call <see cref="TopDocs"/> and work with the
		/// returned <see cref="ITopDocs"/> object, which will contain all the results this
		/// search execution collected.</br></br>
		///</summary>
		ITopDocs GetTopDocs(int start, int howMany);
	}
}